const { Service } = require('egg')
const cheerio = require('cheerio')
// 加密需要的函数库
const { AESencrypt } = require('../utils/AES')

module.exports = class LoginService extends Service {
  /**
   * ! 模拟登录，获取cookie
   * @return {setCookie: string, status: number} **
   */
  async getCookie() {
    const result = { setCookie: '', status: 500 }
    const allCookie = []
    try {
      const { ctx } = this
      // 从前端获取到账号密码信息
      const { sid, pwd } = ctx.data

      // 通过对网页的检查，发现是对密码进行了AES加密，开始进行网页登录模拟
      // 模拟登录门户网站，获取盐值,Portal website-门户网站
      // eslint-disable-next-line max-len
      const homeUrl = 'http://authserver.webvpn.csuft.edu.cn/authserver/login?service=http%3A%2F%2Fwebvpn.csuft.edu.cn%2Fusers%2Fauth%2Fcas%2Fcallback%3Furl'
      const homeRes = await ctx.curl(homeUrl, {
        method: 'GET',
        headers: {
          'Upgrade-Insecure-Requests': '1',
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
        },
      })
      // 加载门户页面的信息，获取密码盐值，留作加密使用
      const $ = cheerio.load(homeRes.data.toString())
      const salt = $('script').text()
      const saltKey = salt.match(/var pwdDefaultEncryptSalt = "([^"]+)"/)[1]
      const encryptedData = AESencrypt(pwd, saltKey)

      // 从门户网页获取it，dllt，execution，_eventId，rmShown
      const hiddenFields = {
        lt: '', dllt: '', execution: '', _eventId: '', rmShown: '',
      }
      const hiddenKeys = Object.keys(hiddenFields)
      hiddenKeys.forEach((e) => {
        hiddenFields[e] = $(`input[name="${e}"]`).val()
      })
      let setCookie = ''
      homeRes.headers['set-cookie'].forEach((e) => {
        if (e.startsWith('JSESSIONID')) {
          setCookie = `${setCookie + e};` // 分割字符串，获取等号后面的值
        }
        allCookie.push(e)
      })

      // 正式携带表单，登录门户网站
      const loginRes = await ctx.curl(homeUrl, {
        method: 'POST',
        headers: {
          Cookie: setCookie,
          'Upgrade-Insecure-Requests': '1',
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
        },
        data: {
          username: sid,
          password: encryptedData,
          lt: hiddenFields.lt,
          dllt: hiddenFields.lt,
          execution: hiddenFields.execution,
          _eventId: hiddenFields._eventId,
          rmShown: hiddenFields.rmShown,
        },
      })
      loginRes.headers['set-cookie'].forEach((e) => {
        if (e.startsWith('iPlanetDirectoryPro')) {
          setCookie = `${setCookie + e};`
        }
        allCookie.push(e)
      })
      // console.log('allCookie', allCookie);
      if (loginRes.status !== 302) { return { setCookie: '', status: loginRes.status } }
      // console.log('loginRes.status', loginRes.status);

      // 第一次重定向
      const reUrl1 = loginRes.headers.location
      const res1 = await ctx.curl(reUrl1, {
        method: 'GET',
        headers: {
          Cookie: allCookie.join(';'),
          'Content-Type': 'application/x-www-form-urlencoded',
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
        },
      })
      if (res1.status !== 302) { return { setCookie: '', status: res1.status } }
      res1.headers['set-cookie'].forEach((e) => {
        if (e.startsWith('_webvpn_key')) {
          setCookie = `${setCookie + e};`
        }
        if (e.startsWith('webvpn_username')) {
          setCookie = `${setCookie + e};`
        }
        allCookie.push(e)
      })
      // console.log('res1.status', res1.status);

      // 第二次重定向
      const reUrl2 = res1.headers.location
      const res2 = await ctx.curl(reUrl2, {
        method: 'GET',
        headers: {
          Cookie: allCookie.join(';'),
          'Content-Type': 'application/x-www-form-urlencoded',
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
        },
      })
      res2.headers['set-cookie'].forEach((e) => {
        if (e.startsWith('_webvpn_key')) {
          setCookie = `${setCookie + e};`
        }
        if (e.startsWith('webvpn_username')) {
          setCookie = `${setCookie + e};`
        }
        allCookie.push(e)
      })
      if (res2.status !== 302) { return { setCookie: '', status: res2.status } }
      // console.log('res2.status', res2.status);

      // 门户网站登录成功，第三次重定向
      const reUrl3 = res2.headers.location
      const res3 = await ctx.curl(reUrl3, {
        method: 'GET',
        headers: {
          Cookie: allCookie.join(';'),
          'Content-Type': 'application/x-www-form-urlencoded',
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
        },
      })
      res3.headers['set-cookie'].forEach((e) => {
        if (e.startsWith('_webvpn_key')) {
          setCookie = `${setCookie + e};`
        }
        if (e.startsWith('webvpn_username')) {
          setCookie = `${setCookie + e};`
        }
        allCookie.push(e)
      })
      if (res3.status !== 200) { return { setCookie: '', status: res3.status } }
      allCookie.forEach((e) => {
        if (e.startsWith('route') && !setCookie.includes('route')) {
          setCookie = `${setCookie + e};`
        }
        if (e.startsWith('CASTGC')) {
          setCookie = `${setCookie + e};`
        }
      })
      setCookie = setCookie.replace(/ /g, '').replace(/domain=([^;]+)/g, ';')
        .replace(/path=([^;]+)/g, ';').replace(/HttpOnly/g, '').replace(/；/g, ';').replace(/;+;/g, ';')
      // console.log('res3.status', res3.status);

      // 访问教务管理系统
      // begin
      const tempUrl = 'http://jwgl.webvpn.csuft.edu.cn'
      const temRes = await ctx.curl(tempUrl, {
        method: 'GET',
        headers: {
          Cookie: allCookie.join(';'),
          // Host: 'jwgl.webvpn.csuft.edu.cn',
          // Referer: 'http://webvpn.csuft.edu.cn/',
          // eslint-disable-next-line max-len
          // Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
          'Upgrade-Insecure-Requests': '1',
          'Content-Type': 'application/x-www-form-urlencoded',
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
        },
      })
      if (temRes.status !== 302) { return { setCookie: '', status: temRes.status } }
      temRes.headers['set-cookie'].forEach((e) => {
        if (e.startsWith('SERVERID')) {
          setCookie = `${setCookie + e};`
        }
        allCookie.push(e)
      })
      // console.log('temRes.status', temRes.status);

      // 访问重定向开始的网页
      const RedirectUrl = 'http://authserver.webvpn.csuft.edu.cn/authserver/login?service=http%3A%2F%2Fjwgl.csuft.edu.cn%2F'
      const resUrl = await ctx.curl(RedirectUrl, {
        method: 'GET',
        headers: {
          Cookie: allCookie.join(';'),
          // eslint-disable-next-line max-len
          Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
          'Content-Type': 'application/x-www-form-urlencoded',
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
        },
      })
      if (resUrl.status !== 302) { return { setCookie: '', status: resUrl.status } }
      // console.log('resUrl.status', resUrl.status);

      // 第一次重定向
      const RedirectUrl1 = resUrl.headers.location
      // console.log('RedirectUrl1', RedirectUrl1);
      const resFirst = await ctx.curl(RedirectUrl1, {
        method: 'GET',
        headers: {
          Cookie: allCookie.join(';'),
          // eslint-disable-next-line max-len
          Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
          'Content-Type': 'application/x-www-form-urlencoded',
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
        },
      })
      if (resFirst.status !== 302) { return { setCookie: '', status: resFirst.status } }
      // console.log('resFirst.status', resFirst.status);

      // 第二次重定向
      const redirectUrl2 = resFirst.headers.location
      // console.log('redirectUrl2', redirectUrl2);
      const resSec = await ctx.curl(redirectUrl2, {
        method: 'GET',
        headers: {
          Cookie: allCookie.join(';'),
          'Content-Type': 'application/x-www-form-urlencoded',
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
        },
      })
      // console.log('resSec.headers', resSec.headers);
      if (resSec.status !== 302) { return { setCookie: '', status: resSec.status } }
      resSec.headers['set-cookie'].forEach((e) => {
        // if (e.startsWith('JSESSIONID')) {
        //   setCookie = setCookie + e + ';'; // 分割字符串，获取等号后面的值
        // }
        allCookie.push(e)
      })
      // console.log('resSec.status', resSec.status);
      // console.log('setCookie', setCookie);
      // 登录教务，第三次重定向
      const eaUrl = resSec.headers.location
      // console.log('eaUrl', eaUrl);
      const eaRes = await ctx.curl(eaUrl, {
        method: 'GET',
        headers: {
          Cookie: allCookie.join(';'),
          // eslint-disable-next-line max-len
          Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
          'Content-Type': 'application/x-www-form-urlencoded',
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
        },
      })
      if (eaRes.status !== 200) { return { setCookie: '', status: eaRes.status } }
      // console.log('eaRes.status', eaRes.status);
      // end

      // 设置返回结果
      result.setCookie = setCookie
      result.status = resSec.status

      return result
    } catch (err) {
      console.log(err)
      return result
    }
  }
}
